var axios = require("axios").default
const Wechatpi = require("wechat-api")
const logger = require("./logger")
let weChatProto = Wechatpi.prototype
Wechatpi.mixin(require("./wechat.extend/msg"))
// Wechatpi.mixin(require("./wechat.extend/genCode"))
let hasOwnProperty = Object.prototype.hasOwnProperty
let querystring = require("querystring")

/**
 * @extends {import("egg").WechatApiME}
 */
class PromWxApi {
	static init() {
		this.apiMap = new Map()
		for (const key in weChatProto) {
			if (weChatProto[key].constructor == Function) {
				if (!hasOwnProperty.call(this.prototype, key)) // 防止自身被重写
					this.prototype[key] = async function () {
						console.log("hook API")
						var args = arguments
						return new Promise((resolve, _reject) => {
							this.base[key](...args, function (err, data) {
								if (err) {
									resolve({code: err.code, message: err.message})
								} else {
									resolve(data)
								}
							})
						})
					}
			}
		}
	}
	/**
	 * 
	 * @param {{token:string,appid:string,encodingAESKey:string,AppSecret:string}} ctx 
	 * @returns {import("egg").WechatApiME}
	 */
	static getInstance(ctx) {
		let api = this.apiMap.get(JSON.stringify(ctx))
		if (!api) {
			api = new PromWxApi(ctx)
			this.apiMap.set(JSON.stringify(ctx), api)
			return api
		}
		return api
	}
	constructor(ctx) {
		this.appid = ctx.appid
		this.base = new Wechatpi(ctx.appid, ctx.AppSecret, (cb) => {
			cb && cb(null, this.token)
		})
		this.axios = axios.create({baseURL: this.base.endpoint})
	}
	/**
	 * 
	 * @param {Function} method 
	 * @param {*} args 
	 */
	async preRequest(method, args) {
		if (!this.token || this.token.expireTime < Date.now()) {
			this.token = await this.getAccessToken()
		}
		method && method.apply(this, args)
	}
	async getAccessToken() {
		var url = "/cgi-bin/token?grant_type=client_credential&appid=" + this.appid + "&secret=" + this.base.appsecret
		let data = (await this.axios.get(url)).data
		var expireTime = (new Date().getTime()) + (data.expires_in - 10) * 1000
		return {expireTime, accessToken: data.access_token}
	}
	async getWXACode({line_color, auto_color = false, width = 430, path = "/"}) {
		await this.preRequest()
		let data = await this.axios.post("/wxa/getwxacode", {line_color, auto_color, width, path}, {
			params: {access_token: this.token.accessToken},
			responseType: "stream"
		})
		return data.data
	}

	async getWXACodeUnlimit({line_color = {"r": "0", "g": "0", "b": "0"}, auto_color = false, width = 430, path = "/", scene = {}}) {
		await this.preRequest()
		let data = await this.axios.post("/wxa/getwxacodeunlimit", {
			line_color, auto_color, width, path,
			is_hyaline: true,
			scene: querystring.stringify(scene)
		}, {
			params: {
				access_token: this.token.accessToken
			},
			responseType: "stream"
		})
		return data.data
	}
}
PromWxApi.init()

/*  var p = PromWxApi.getInstance({
	token: "wechat_2041",
	appid: "wx83a9214437fc4521",
	encodingAESKey: "",
	AppSecret: "a3469234704dae229e28f422bc7b80b5"
})
let mp = p.sendPromMsg({})
mp.then(async (v) => {
	console.log(v)
})
 */
module.exports = {PromWxApi}